package com.softline.documentsmall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.softline.documentsmall.dao.ClassificationMapper;
import com.softline.documentsmall.dao.DictionaryMapper;
import com.softline.documentsmall.dao.EntryDetailSubmitMapper;
import com.softline.documentsmall.dao.LogAnalyseMapper;
import com.softline.documentsmall.entity.Classification;
import com.softline.documentsmall.entity.Dictionary;
import com.softline.documentsmall.entity.LogAnalyse;
import com.softline.documentsmall.service.LogAnalyseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

import static com.softline.documentsmall.service.impl.DictionaryServiceImp.languageType;

/**
 * @Author wph
 * @Date 2021/1/22 9:35
 */
@Service
@Slf4j
public class LogAnalyseServiceImpl implements LogAnalyseService {

    @Autowired
    private EntryDetailSubmitMapper entryDetailSubmitMapper;
    @Autowired
    private LogAnalyseMapper logAnalyseMapper;
    @Autowired
    private DictionaryServiceImp dictionaryServiceImp;
    @Autowired
    private ClassificationMapper classificationMapper;
    @Autowired
    private DictionaryMapper dictionaryMapper;
    //已查看词汇图谱中未查看图谱数量
    private static int noAccess = 2;
    private static int defaultInt = 0;

    /**
     * 根据语言,用户ID查询6大图表数据
     *
     * @param type   术语类型
     * @param userId 用户id
     * @return
     */
    @Override
    public JSONObject selectList(String type, String userId) {
        JSONObject result = new JSONObject();
        //查询5 词条语言分布
        JSONObject languageTrend = selectLanguage(userId);
        result.put("languageTrend", languageTrend);
        //用户非空时 ,查询1 日历
        if (userId != null && !"".equals(userId)) {
            JSONArray calendarArray = selectCalendar(userId);
            result.put("calendar", calendarArray);
            //按照4级术语查询已查看词汇占比,
            int percent = selectPercent(userId);
            result.put("percent", percent);
        } else {
            //IDw为空  返回0或者NULL
            result.put("calendar", new JSONArray());
            result.put("percent", 0);
        }
        //查询词条编辑趋势
        JSONObject editHistoryCount = selectEditHistory(userId);
        result.put("editHistory", editHistoryCount);
        //查询用户词条类型访问分布  查看4级数量算作一级总数
        JSONObject typeDistribution = selectType(type, userId);
        result.put("typeDistribution", typeDistribution);
        return result;
    }

    /**
     * 根据用户id 语种查询知识图谱
     *
     * @param type
     * @param userId
     * @return
     */
    @Override
    public JSONObject selectKnowledge(String type, String userId) {
        JSONObject resultObject = new JSONObject();
        JSONArray arr = new JSONArray();
        JSONObject oneObject = new JSONObject();
        JSONArray userArray = new JSONArray();
        //根据用户ID,语种类型去查询用户看过的术语知识图谱
        List<Map<String, Object>> listLogAnalyse = logAnalyseMapper.selectKnowledge(type, userId);
        if (listLogAnalyse != null && listLogAnalyse.size()>0) {
            String firstString = listLogAnalyse.get(0).get("first_type").toString();
            //先只查第一个树
            listLogAnalyse.forEach(item -> {
                String firstType = item.get("first_type").toString();
                if (firstType.equals(firstString)) {
                    //所有四级放到数组中
                    userArray.add(item.get("fourth_type").toString());
                }
            });
            //查询该一级分类下所有二级分类
            List<Map<String, Object>> secondList = classificationMapper.selectSeconds(firstString);
            JSONArray twoChild = new JSONArray();
            secondList.forEach(item -> {
                JSONArray threeChild = new JSONArray();
                JSONObject twoObject = new JSONObject();
                String secondString = item.get("second_type").toString();
                //查询该二级分类下所有三级分类,和ID
                List<Classification> ThirdList = classificationMapper.selectThirdList(secondString);
                ThirdList.forEach(temp -> {
                            JSONArray fourChild = new JSONArray();
                            JSONObject threeObject = new JSONObject();
                            Integer classificationId = temp.getId();
                            String thirdType = temp.getThirdType();
                            //三级分类ID查询对应语种四级分类名字
                            List<Dictionary> fourArray = selectFour(type, classificationId);
                            if (fourArray != null && fourArray.size() > 0) {
                                for (int i = 0; i < fourArray.size(); i++) {
                                    Dictionary dictionary = fourArray.get(i);
                                    Integer dictionaryId = dictionary.getId();
                                    String fourName = dictionary.getNameCn();
                                    JSONObject jsonObject = new JSONObject();
                                    //四级分类循环比对,相同,不同均放入数据集
                                    if (userArray.contains(fourName)) {
                                        jsonObject.put("value", fourName);
                                        jsonObject.put("dictionaryId", dictionaryId);
                                        jsonObject.put("hasView", 1);
                                        fourChild.add(jsonObject);
                                    } else if (defaultInt < noAccess) {
                                        jsonObject.put("value", fourName);
                                        jsonObject.put("dictionaryId", dictionaryId);
                                        jsonObject.put("hasView", 0);
                                        defaultInt++;
                                        fourChild.add(jsonObject);
                                    }
                                }
                                defaultInt = 0;
                            }
                            if (fourChild != null && fourChild.size() > 0) {
                                threeObject.put("name", thirdType);
                                threeObject.put("child", fourChild);
                                threeChild.add(threeObject);
                            }
                        }
                );
                if (threeChild != null && threeChild.size() > 0) {
                    twoObject.put("name", secondString);
                    twoObject.put("child", threeChild);
                    twoChild.add(twoObject);
                }
            });
            oneObject.put("levelOne", firstString);
            oneObject.put("levelTwo", twoChild);
        }
        arr.add(oneObject);
        if (type.equals("en")) {
            resultObject.put("value", "Big Data");
        } else if (type.equals("cn")) {
            resultObject.put("value", "大数据");
        }
        resultObject.put("arr", arr);
        return resultObject;
    }

    /**
     * 根据词条多级分类表id和语种类别查询对应语种
     *
     * @param type
     * @param id
     * @return
     */
    private List<Dictionary> selectFour(String type, Integer id) {
        List<Dictionary> dictionaryList = dictionaryMapper.selectFourList(id, type);
        List<Dictionary> resultArra = new ArrayList<Dictionary>();
        if (dictionaryList != null && dictionaryList.size() > 0) {
            for (int i1 = 0; i1 < dictionaryList.size(); i1++) {
//                JSONObject jsonObject = new JSONObject();
                Dictionary newDictionary = new Dictionary();
                Dictionary dictionary = dictionaryList.get(i1);
                String Temp = "";
                switch (type) {
                    case "en":
                        Temp = dictionary.getNameEn();
                        break;
                    case "cn":
                        Temp = dictionary.getNameCn();
                        break;
                    case "ar":
                        Temp = dictionary.getNameAr();
                        break;
                    case "fr":
                        Temp = dictionary.getNameFr();
                        break;
                    case "de":
                        Temp = dictionary.getNameDe();
                        break;
                    case "it":
                        Temp = dictionary.getNameIt();
                        break;
                    case "jp":
                        Temp = dictionary.getNameJp();
                        break;
                    case "kr":
                        Temp = dictionary.getNameKr();
                        break;
                    case "pt":
                        Temp = dictionary.getNamePt();
                        break;
                    case "ru":
                        Temp = dictionary.getNameRu();
                        break;
                    case "es":
                        Temp = dictionary.getNameEs();
                        break;
                }
//                jsonObject.put("id",dictionary.getId());
////                jsonObject.put("name",Temp);
                newDictionary.setNameCn(Temp);
                newDictionary.setId(dictionary.getId());
//                resultArra.add(jsonObject);
                resultArra.add(newDictionary);
            }
        }
        return resultArra;
    }

    private JSONObject selectType(String type, String userId) {
        JSONObject resultObject = new JSONObject();
        List<Map<String, Object>> firstTypeList = classificationMapper.selectFirstTypeByGroupBy(type);
        if (firstTypeList != null && !ObjectUtils.isEmpty(firstTypeList)) {
            JSONArray classificationArray = changeClassificationArray(firstTypeList);
            resultObject.put("key", classificationArray);
            List<Map<String, Object>> userTypeList = logAnalyseMapper.selectFirstTypeByUserAndUserId(userId, type);
            resultObject.put("me", changeFormatTwo(classificationArray, userTypeList));
            List<Map<String, Object>> allTypeList = logAnalyseMapper.selectFirstTypeByAll(type);
            resultObject.put("all", changeFormatTwo(classificationArray, allTypeList));
        } else {
            //一级词条类型为空 全部为空
            resultObject.put("key", new JSONArray());
            resultObject.put("me", new JSONArray());
            resultObject.put("all", new JSONArray());
        }
        return resultObject;
    }

    /**
     * 改变一级术语格式为数组
     *
     * @param firstTypeList
     * @return
     */
    private JSONArray changeClassificationArray(List<Map<String, Object>> firstTypeList) {
        JSONArray resultArray = new JSONArray();
        firstTypeList.forEach(item -> {
            resultArray.add(item.get("first_type"));
        });
        return resultArray;
    }

    /**
     * 查询已查看词汇占比,4级术语,算到1级中
     *
     * @param userId
     * @return
     */
    public int selectPercent(String userId) {
        //查询已查看词汇
        Map<String, Object> countMap = logAnalyseMapper.selectPercent(userId);
        Long countFourth = Long.parseLong(countMap.get("count").toString());
        //查询4级词汇总数
        Long countFirst = dictionaryMapper.selectCount();
        // 创建bai一个数du值格式化对象zhi  
        NumberFormat numberFormat = NumberFormat.getInstance();
// 设置精确到小数点后dao2位zhuan  
        numberFormat.setMaximumFractionDigits(2);
        int round = Math.round((float) countFourth / (float) countFirst * 100);
        return round;
    }

    /**
     * 根据用户ID 查询最近9天编辑历史数据
     *
     * @param userId
     * @return
     */
    private JSONObject selectEditHistory(String userId) {
        JSONObject resultObject = new JSONObject();
        JSONArray timeArray = getNineDay();
        resultObject.put("key", timeArray);
        if (userId != null && !"".equals(userId)) {
            List<Map<String, Object>> resultMe = entryDetailSubmitMapper.selectMeEditHistory(userId);
            List<Map<String, Object>> resultAll = entryDetailSubmitMapper.selectAllEditHistory();
            resultObject.put("me", changeFormat(resultMe, timeArray));
            resultObject.put("all", changeFormat(resultAll, timeArray));
        } else {
            List<Map<String, Object>> resultAll = entryDetailSubmitMapper.selectAllEditHistory();
            resultObject.put("me", new JSONArray());
            resultObject.put("all", changeFormat(resultAll, timeArray));
        }
        return resultObject;
    }

    /**
     * 更改日期和修改语种数格式
     *
     * @param temp      原始修改语种数
     * @param timeArray
     * @return
     */
    private Object changeFormat(List<Map<String, Object>> temp, JSONArray timeArray) {
        JSONArray DateArray = new JSONArray();
        if (temp != null && !ObjectUtils.isEmpty(temp)) {
            timeArray.forEach(tempDate -> {
                AtomicReference<Integer> defaultInt = new AtomicReference<>(0);
                temp.forEach(itme -> {
                    if (tempDate.equals(itme.get("date"))) {
                        defaultInt.set(Integer.parseInt(itme.get("count").toString()));
                    }
                });
                DateArray.add(defaultInt.get());
            });
        }
        return DateArray;
    }

    /**
     * 根据一级语种更改访问语种数类型
     *
     * @param classificationArray 一级语种数
     * @param userTypeList        访问类型
     * @return
     */
    private JSONArray changeFormatTwo(JSONArray classificationArray, List<Map<String, Object>> userTypeList) {
        JSONArray DateArray = new JSONArray();
        if (userTypeList != null && !ObjectUtils.isEmpty(userTypeList)) {
            classificationArray.forEach(temp -> {
                AtomicReference<Integer> defaultInt = new AtomicReference<>(0);
                userTypeList.forEach(itme -> {
                    if (temp.equals(itme.get("first_type"))) {
                        defaultInt.set(Integer.parseInt(itme.get("count").toString()));
                    }
                });
                DateArray.add(defaultInt.get());
            });
        }
        return DateArray;
    }

    /**
     * 获取当前天数与9天前之间所有日期
     *
     * @return
     */
    private JSONArray getNineDay() {
        JSONArray dateArray = new JSONArray();
        //获取当前时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        String nowDate = simpleDateFormat.format(calendar.getTime());
        dateArray.add(nowDate);
        for (int i = 8; i > 0; i--) {
            calendar.add(Calendar.DATE, -1);
            dateArray.add(simpleDateFormat.format(calendar.getTime()));
        }
        return dateArray;
    }

    /**
     * 根据用户ID查询访问记录
     *
     * @param userId
     * @return
     */
    private JSONArray selectCalendar(String userId) {
        JSONArray resultArray = new JSONArray();
        List<Map<String, Object>> calendarMap = logAnalyseMapper.selectCalendar(userId);
        calendarMap.forEach(item -> {
            resultArray.add(item.get("create_date"));
        });
        return resultArray;
    }

    /**
     * 查询 词条语言查看分布数据
     *
     * @param userId
     * @return
     */
    private JSONObject selectLanguage(String userId) {
        JSONObject jsonObject = new JSONObject();
        JSONArray allData = new JSONArray();
        List<Map<String, Object>> langList = logAnalyseMapper.selectLanguage();
        allData = changeSort(langList);
        jsonObject.put("allData", allData);
        JSONArray myData = new JSONArray();
        if (userId != null && !"".equals(userId)) {
            List<Map<String, Object>> meLangList = logAnalyseMapper.selectLanguageForMe(userId);
            myData = changeSort(meLangList);
        }
        jsonObject.put("myData", myData);
        jsonObject.put("xData", languageType);
        return jsonObject;
    }

    /**
     * 更改词条语言数据格式,查询某语言为空时赋值0
     *
     * @param meLangList
     * @return
     */
    private JSONArray changeSort(List<Map<String, Object>> meLangList) {
        JSONArray result = new JSONArray();
        for (int j = 0; j < languageType.length; j++) {
            for (int i = 0; i < meLangList.size(); i++) {
                Map<String, Object> stringObjectMap = meLangList.get(i);
                String language = stringObjectMap.get("language").toString();
                int temp = 0;
                if (languageType[j].equals(language)) {
                    switch (language) {
                        case "en":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "cn":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "ar":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "fr":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "de":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "it":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "jp":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "kr":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "pt":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "ru":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                        case "es":
                            temp = Integer.parseInt(stringObjectMap.get("count").toString());
                            break;
                    }
                    result.add(temp);
                }
                //如果匹配到最后, 并且没有添加过数字,默认添加0
                if (i == meLangList.size() - 1 && j >= result.size()) {
                    result.add(temp);
                }
            }
        }
        return result;
    }

    /**
     * 根据术语ID和语种类型添加到日志中
     *
     * @param dictionary 术语实体
     * @param type       语种类型
     * @Author wph
     */
    public void insertLog(Dictionary dictionary, String type, String userId) {
        if (!ObjectUtils.isEmpty(dictionary)) {
            LogAnalyse logAnalyse = new LogAnalyse();
            String fourthName = dictionaryServiceImp.selectName(type, dictionary);
            logAnalyse.setFourthType(fourthName);
            logAnalyse.setLanguage(type);
            logAnalyse.setPassportId(userId);
            int classificationId = dictionaryServiceImp.selectDictionaryId(type, dictionary);
            Classification classification = classificationMapper.selectByPrimaryKey(classificationId);
            if (!ObjectUtils.isEmpty(classification)) {
                logAnalyse.setFirstType(classification.getFirstType());
            }
            logAnalyseMapper.insert(logAnalyse);
        }
    }
}
